\subsubsection{ARM: \OptimizingKeilVI (\ARMMode)}
\label{sec:SwitchARMLot}

\lstinputlisting[caption=\OptimizingKeilVI (\ARMMode),style=customasmARM]{patterns/08_switch/2_lot/lot_ARM_ARM_O3.asm}

Ce code utilise les caractéristiques du mode ARM dans lequel toutes les instructions
ont une taille fixe de 4 octets.

Gardons à l'esprit que la valeur maximale de $a$ est 4 et que toute autre valeur
supérieure provoquera l'affichage de la chaîne \IT{<<something unknown\textbackslash{}n>>}

\myindex{ARM!\Instructions!CMP}
\myindex{ARM!\Instructions!ADDCC}
La première instruction \TT{CMP R0, \#5} compare la valeur entrée dans $a$ avec 5.

\footnote{ADD---addition}
L'instruction suivante, \TT{ADDCC PC, PC, R0,LSL\#2}, est exécutée si et seulement
si $R0 < 5$ (\IT{CC=Carry clear / Less than} retenue vide, inférieur à).
Par conséquent, si \TT{ADDCC} n'est pas exécutée (c'est le cas $R0 \geq 5$), un
saut au label \IT{default\_case} se produit.

Mais si $R0 < 5$ et que \TT{ADDCC} est exécuté, voici ce qui se produit:

La valeur dans \Reg{0} est multipliée par 4.
En fait, le suffixe de l'instruction \TT{LSL\#2} signifie \q{décalage à gauche de 2 bits}.
Mais comme nous le verrons plus tard~(\myref{division_by_shifting}) dans la section
\q{\ShiftsSectionName}, décaler de 2 bits vers la gauche est équivalent à multiplier
par 4.

Puis, nous ajoutons $R0*4$ à la valeur courante du \ac{PC}, et sautons à l'une
des instructions \TT{B} (\IT{Branch}) situées plus bas.

Au moment de l'exécution de \TT{ADDCC}, la valeur du \ac{PC} est en avance de 8
octets (\TT{0x180}) sur l'adresse à laquelle l'instruction \TT{ADDCC} se trouve
(\TT{0x178}), ou, autrement dit, en avance de 2 instructions.

\myindex{ARM!Pipeline}

C'est ainsi que le pipeline des processeurs ARM fonctionne: lorsque \TT{ADDCC} est
exécutée, le processeur, à ce moment, commence à préparer les instructions après
la suivante, c'est pourquoi \ac{PC} pointe ici. Cela doit être mémorisé.

Si $a=0$, elle sera ajoutée à la valeur de \ac{PC}, et la valeur courante de \ac{PC}
sera écrite dans \ac{PC} (qui est 8 octets en avant) et un saut au label \IT{loc\_180}
sera effectué, qui est 8 octets en avant du point où l'instruction se trouve.

Si $a=1$, alors $PC+8+a*4 = PC+8+1*4 = PC+12 = 0x184$ sera écrit dans \ac{PC}, qui
est l'adresse du label \IT{loc\_184}.

A chaque fois que l'on ajoute 1 à $a$, le \ac{PC} résultant est incrémenté de
4.

4 est la taille des instructions en mode ARM, et donc, la longueur de chaque instruction
\TT{B} desquelles il y a 5 à la suite.

Chacune de ces cinq instructions \TT{B} passe le contrôle plus loin, à ce qui a
été programmé dans le \IT{switch()}.

Le chargement du pointeur sur la chaîne correspondante se produit ici, etc.

\subsubsection{ARM: \OptimizingKeilVI (\ThumbMode)}

\lstinputlisting[caption=\OptimizingKeilVI (\ThumbMode),style=customasmARM]{patterns/08_switch/2_lot/lot_ARM_thumb_O3.asm}

\myindex{ARM!\ThumbMode}
\myindex{ARM!\ThumbTwoMode}

On ne peut pas être sûr que toutes ces instructions en mode Thumb et Thumb-2 ont
la même taille. On peut même dire que les intructions dans ces modes ont une longueur
variable, tout comme en x86.

\myindex{jumptable}

Donc, une table spéciale est ajoutée, qui contient des informations sur le nombre
de cas (sans inclure celui par défaut), et un offset pour chaque label auquel le
contrôle doit être passé dans chaque cas.

\myindex{ARM!Mode switching}
\myindex{ARM!\Instructions!BX}

Une fonction spéciale est présente ici qui s'occupe de la table et du passage du
contrôle, appelée \IT{\_\_ARM\_common\_switch8\_thumb}.
Elle commence avec \TT{BX PC}, dont la fonction est de passer le mode du processeur
en ARM.
Ensuite, vous voyez la fonction pour le traitement de la table.

C'est trop avancé pour être détaillé ici, donc passons cela.
% TODO explain it...

\myindex{ARM!\Registers!Link Register}

Il est intéressant de noter que la fonction utilise le regsitre \ac{LR} comme un
pointeur sur la table.

En effet, après l'appel de cette fonction, \ac{LR} contient l'adresse après\\
l'instruciton \TT{BL \_\_ARM\_common\_switch8\_thumb}, oú la table commence.

Il est intéressant de noter que le code est généré comme une fonction indépendante
afin de la ré-utiliser, donc le compilateur ne génèrera pas le même code pour chaque
déclaration switch().

\IDA l'a correctement identifié comme une fonction de service et une table, et a
ajouté un commentaire au label comme\\
\TT{jumptable 000000FA case 0}.

